/*
 * @Author: 0x9DEFA478
 * @Date: 2024-07-21 20:36:23
 * @LastEditTime: 2024-09-22 20:34:34
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "./H_TS_Thread.h"
#include "../LL/H_TS_LL.h"




typedef struct{
  H_TS_Thread* Thread;
  void* volatile* Stack;
  Hsize StackSize;
  char* ThreadName;
}H_TS_Thread_Mem;




static const H_TS_ThreadAttribute H_TS_ThreadAttributeDefault=vH_TS_ThreadAttributeDefault;




static void new_H_TS_Thread_Mem(H_TS_Thread_Mem* Thread_Mem,Hsize StackSize,const char* ThreadName){
  Hsize Size;
  Hsize ThreadNameLength;
  int H_TS_IsStart;

  ThreadNameLength=0;
  if(ThreadName!=NULL){
    while(ThreadName[ThreadNameLength]!='\0'){
      ThreadNameLength++;
    }
    if(ThreadNameLength>0){
      ThreadNameLength++;
    }
  }

  Size=sizeof(H_TS_Thread);
  Size+=(sizeof(void*)*vH_TS_LL_StackPtrAlign-1);
  Size/=(sizeof(void*)*vH_TS_LL_StackPtrAlign);
  Size*=(sizeof(void*)*vH_TS_LL_StackPtrAlign);
  
  if(StackSize==0){
    StackSize=vH_TS_StackSizeDefault;
  }

  StackSize+=((sizeof(void*)*vH_TS_LL_StackPtrAlign)-1);
  StackSize/=(sizeof(void*)*vH_TS_LL_StackPtrAlign);
  StackSize*=(sizeof(void*)*vH_TS_LL_StackPtrAlign);


  if(H_TS_LL_Core_Instance.CurrentThread==NULL){
    H_TS_IsStart=0;
  }else{
    H_TS_IsStart=-1;
    oH_TS_LL_SchedulerSuspend();//挂起线程调度
  }

  Thread_Mem->Thread=H_TS_LL_Core_Instance.Memory.Malloc(Size+StackSize+ThreadNameLength);
  
  if(H_TS_IsStart!=0){
    oH_TS_LL_ResumeSchedulerAuto();//允许线程调度
  }

  if(Thread_Mem->Thread==NULL){
    return;
  }

  Thread_Mem->Stack=&((void* volatile*)Thread_Mem->Thread)[Size/sizeof(void*)];
  Thread_Mem->StackSize=StackSize;

  if(ThreadNameLength<=0){
    Thread_Mem->ThreadName=NULL;
  }else{
    Thread_Mem->ThreadName=(char*)&((void* volatile*)Thread_Mem->Thread)[(Size+StackSize)/sizeof(void*)];

    for(Hsize i=0;i<ThreadNameLength;i++){
      Thread_Mem->ThreadName[i]=ThreadName[i];
    }
  }

}

static void ThreadStart(H_TS_Thread* Thread){
  H_TS_Thread* p;
  int H_TS_IsStart;
  
  Hsize Priority;
  int retVal;

  if(H_TS_LL_Core_Instance.CurrentThread==NULL){
    H_TS_IsStart=0;
  }else{
    H_TS_IsStart=-1;

    oH_TS_LL_SchedulerSuspend();//挂起线程调度
  }

  //添加到待添加线程链表
  p=H_TS_LL_Core_Instance.WaitAddThreads;
  Thread->AllList.Last=NULL;
  Thread->AllList.Next=p;
  if(p!=NULL){
    p->AllList.Last=Thread;
  }
  H_TS_LL_Core_Instance.WaitAddThreads=Thread;

  H_TS_LL_ThreadAddToReadyList(Thread,p,Priority,retVal);
  if(H_TS_IsStart!=0){
    if(retVal==0){
      oH_TS_LL_ResumeSchedulerAuto();
    }else{
      oH_TS_LL_ResumeSchedulerFixed();
    }
  }

}




H_TS_Thread* H_TS_StartNewThread(int (*Code)(void*),void* v,const H_TS_ThreadAttribute* Attribute){
  H_TS_Thread_Mem Thread_Mem;
  H_TS_LL_ThreadInitParam ThreadInitParam;

  if(Attribute==NULL){
    Attribute=&H_TS_ThreadAttributeDefault;
  }

  new_H_TS_Thread_Mem(&Thread_Mem,Attribute->StackSize,Attribute->ThreadName);

  if(Thread_Mem.Thread==NULL){
    return Thread_Mem.Thread;
  }

  ThreadInitParam.Priority=Attribute->Priority;
  ThreadInitParam.Stack=Thread_Mem.Stack;
  ThreadInitParam.StackSize=Thread_Mem.StackSize;
  ThreadInitParam.Code=Code;
  ThreadInitParam.v=v;
  ThreadInitParam.ThreadName=Thread_Mem.ThreadName;
  H_TS_LL_ThreadInit(Thread_Mem.Thread,&ThreadInitParam);

  ThreadStart(Thread_Mem.Thread);

  return Thread_Mem.Thread;
}

void H_TS_ThreadExit(int RetVal){
  H_TS_Thread* thisThread;
  H_TS_Thread* p_last;
  H_TS_Thread* p_next;

  thisThread=cH_TS_LL_ThisThread(H_TS_LL_Core_Instance);

  thisThread->RetVal=RetVal;

  oH_TS_LL_SchedulerSuspend();//挂起线程调度

  thisThread->Status=vH_TS_Thread_Status_RequestStop;//修改状态
  
  //从就绪链表里移除
  H_TS_LL_ThreadRemoteThisFromReadyList(thisThread,p_next,p_last);

  //将_this添加到结束链表头部
  p_next=H_TS_LL_Core_Instance.ExitThreads;
  thisThread->List.Exit.Next=p_next;
  H_TS_LL_Core_Instance.ExitThreads=thisThread;

  oH_TS_LL_ResumeSchedulerFixed();//允许线程调度

  for(;;){
  }

}

H_TS_ThreadInfo* H_TS_ThreadInfoListGet(){
  H_TS_Thread* Thread;
  H_TS_ThreadInfo* r;
  H_TS_ThreadInfo* p;

  r=NULL;
  p=NULL;

  oH_TS_LL_SchedulerSuspend();

  Thread=H_TS_LL_Core_Instance.Threads;

  while(Thread!=NULL){
    char* ThreadName;
    Hsize ThreadNameLength;

    ThreadNameLength=0;
    while(Thread->ThreadName[ThreadNameLength]!='\0'){
      ThreadNameLength++;
    }
    ThreadNameLength++;
    
    if(p==NULL){
      r=H_TS_LL_Core_Instance.Memory.Malloc(sizeof(H_TS_ThreadInfo)+ThreadNameLength);
      p=r;
    }else{
      p->Next=H_TS_LL_Core_Instance.Memory.Malloc(sizeof(H_TS_ThreadInfo)+ThreadNameLength);
      p=p->Next;
    }

    if(p==NULL){

      p=r;

      while(p!=NULL){
        r=p->Next;
        H_TS_LL_Core_Instance.Memory.Free(p);
        p=r;
      }

      r=NULL;
      break;
    }

    ThreadName=((char*)&p[1]);
    for(Hsize i=0;i<ThreadNameLength;i++){
      ThreadName[i]=Thread->ThreadName[i];
    }

    p->Next=NULL;
    p->ThreadName=ThreadName;
    p->CPU_Load=Thread->CPU_Load;
    p->Priority=Thread->Priority;
    p->StackMaxUsage=Thread->Stack.MaxUsage;
    p->StackSize=Thread->Stack.Size;
    
    Thread=Thread->AllList.Next;
  }
  
  oH_TS_LL_ResumeSchedulerAuto();

  return r;
}

void H_TS_ThreadInfoListFree(H_TS_ThreadInfo* Info){
  H_TS_ThreadInfo* p;

  if(Info==NULL){
    return;
  }

  p=Info;

  oH_TS_LL_SchedulerSuspend();
  
  while(p!=NULL){
    Info=p->Next;
    H_TS_LL_Core_Instance.Memory.Free(p);
    p=Info;
  }

  oH_TS_LL_ResumeSchedulerAuto();
}



